package com.dart.commons.redis;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import com.dart.framework.common.serializer.ProtoStuffSerializerUtil;
import com.dart.framework.exception.RedisException;

/**
 * Redis for Jedis 缓存管理工具类
 * @author yanghaoquan
 *
 */
public class JedisClientSingle {

	private final Logger logger = LoggerFactory.getLogger(getClass()) ;
	
	@Autowired
	private JedisPool jedisPool;
	
	public String set(String key, String value) {
		return set(key, value, 0) ;
	}
	public String set(String key, String value, int expire) {
		Jedis jedis = jedisPool.getResource() ;
		String result = null ;
		try {
			if(expire != 0) {
				result = jedis.setex(key, expire, value) ;
			} else {
				result = jedis.set(key, value) ;
			}
			logger.debug("Redis Cache ==>> {}", key);
		} catch (Exception e) {
			logger.error("Redis Cache Error ==>> {}", e);
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public String set(byte[] key, byte[] value) {
		return set(key, value, 0) ;
	}
	public String set(byte[] key, byte[] value, int expire) {
		Jedis jedis = jedisPool.getResource() ;
		String result = null ;
		try {
			if(expire != 0) {
				result = jedis.setex(key, expire, value) ;
			} else {
				result = jedis.set(key, value) ;
			}
			logger.debug("Redis Cache ==>> {}", ProtoStuffSerializerUtil.deserialize(key, String.class));
		} catch (Exception e) {
			logger.error("Redis Cache Error ==>> {}", e);
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public String hmset(String key, Map<String, String> hash) {
		Jedis jedis = jedisPool.getResource() ;
		String result = null ;
		try {
			result = jedis.hmset(key, hash) ;
			logger.debug("Redis HashMap Cache ==>> {}", key);
		} catch (Exception e) {
			logger.error("Redis HashMap Cache Error ==>> {}", e);
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public List<String> hmget(String key, String... fields) {
		Jedis jedis = jedisPool.getResource() ;
		List<String> result = null ;
		try {
			result = jedis.hmget(key, fields) ;
			logger.debug("Redis Get HashMap Cache ==>> {}{}", key, fields);
		} catch (Exception e) {
			logger.error("Redis Get HashMap HashMap Cache Error ==>> {}", e);
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Map<String, String> hmgetAll(String key) {
		Jedis jedis = jedisPool.getResource() ;
		Map<String, String> result = null ;
		try {
			result = jedis.hgetAll(key) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Set<String> hkeys(String key) {
		Jedis jedis = jedisPool.getResource() ;
		Set<String> result = null ;
		try {
			result = jedis.hkeys(key) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public Long hlen(String key) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.hlen(key) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public String hmset(byte[] key, Map<byte[], byte[]> hash) {
		Jedis jedis = jedisPool.getResource() ;
		String result = null ;
		try {
			result = jedis.hmset(key, hash) ;
			logger.debug("Redis HashMap Cache ==>> {}", ProtoStuffSerializerUtil.deserialize(key, String.class));
		} catch (Exception e) {
			logger.error("Redis HashMap Cache Error ==>> {}", e);
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public List<byte[]> hmget(byte[] key, byte[]... fields) {
		Jedis jedis = jedisPool.getResource() ;
		List<byte[]> result = null ;
		try {
			result = jedis.hmget(key, fields) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public Map<byte[], byte[]> hmgetAll(byte[] key) {
		Jedis jedis = jedisPool.getResource() ;
		Map<byte[], byte[]> result = null ;
		try {
			result = jedis.hgetAll(key) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public Set<byte[]> hkeys(byte[] key) {
		Jedis jedis = jedisPool.getResource() ;
		Set<byte[]> result = null ;
		try {
			result = jedis.hkeys(key) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Long hlen(byte[] key) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.hlen(key) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	
	public Long lpush(String key, String...strings) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.lpush(key, strings) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Long lpush(byte[] key, byte[]... strings) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.lpush(key, strings) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Long sadd(String key, String...members) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.sadd(key, members) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Long sadd(byte[] key, byte[]... members) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.sadd(key, members) ;
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	
	
	public String get(String key) {
		Jedis jedis = jedisPool.getResource() ;
		String result = null ;
		try {
			result = jedis.get(key) ;
			logger.debug("Redis Hit Cache ==>> {}{}", key, (result!=null?"":" ==> Not Catch"));
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public byte[] get(byte[] key) {
		Jedis jedis = jedisPool.getResource() ;
		byte[] result = null ;
		try {
			result = jedis.get(key) ;
			logger.debug("Redis Hit Cache ==>> {}{}", ProtoStuffSerializerUtil.deserialize(key, String.class), (result!=null?"":" ==> Not Catch"));
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	public Long del(String key) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.del(key) ;
			logger.debug("Redis Del Cache ==>> {}{}", key, (result!=null?" ==> "+result:" ==> Not Catch"));
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Long del(byte[] key) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.del(key) ;
			logger.debug("Redis Del Cache ==>> {}{}", ProtoStuffSerializerUtil.deserialize(key, String.class), (result!=null?" ==> "+result:" ==> Not Catch"));
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Long delHash(String key, String...fields) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.hdel(key, fields) ;
			logger.debug("Redis Del Hash Cache ==>> {}{}", key, (result!=null?" ==> "+result:" ==> Not Catch"));
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public Long delHash(byte[] key, byte[]...fields) {
		Jedis jedis = jedisPool.getResource() ;
		Long result = null ;
		try {
			result = jedis.hdel(key, fields) ;
			logger.debug("Redis Del Hash Cache ==>> {}{}", ProtoStuffSerializerUtil.deserialize(key, String.class), (result!=null?" ==> "+result:" ==> Not Catch"));
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public String flushDB() {
		Jedis jedis = jedisPool.getResource() ;
		String result = null ;
		try {
			result = jedis.flushDB() ;
			logger.debug("Redis flushDB...");
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return result ;
	}
	
	public String flushALL() {
		Jedis jedis = jedisPool.getResource() ;
		String result = null ;
		try {
			result = jedis.flushAll() ;
			logger.debug("Redis flushAll...");
		} catch (Exception e) {
			throw new RedisException() ;
		} finally {
			if (jedis != null) {
                jedis.close();
            }
		}
		return result ;
	}
	
	
	
}
